﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Warensoft.Socket.MessageDataStructs;
namespace Warensoft.Socket.Extension
{
    public static class StreamExtension
    {
       
        public static int ReadInt(this Stream strm)
        {
            var buffer = new byte[4];
            for (int i = 0; i <4; i++)
            {
                buffer[i] = (byte)strm.ReadByte();
            }
            return BitConverter.ToInt32(buffer, 0);
        }
        public static void WriteInt(this Stream strm, int value)
        {
            var buffer = BitConverter.GetBytes(value);
            for (int i = 0; i<4; i++)
            {
                strm.WriteByte(buffer[i]);
            }
        }
        public static short ReadShort(this Stream strm)
        {
            var buffer = new byte[2];
            for (int i = 0; i <2; i++)
            {
                buffer[i] = (byte)strm.ReadByte();
            }
            return BitConverter.ToInt16(buffer, 0);
        }
        public static void WriteShort(this Stream strm, short value)
        {
            var buffer = BitConverter.GetBytes(value);
            for (int i = 0; i<2; i++)
            {
                strm.WriteByte(buffer[i]);
            }
        }

        public static string ReadUTF(this Stream strm)
        {
            var length = strm.ReadShort();
            var buffer = new byte[length];
            strm.Read(buffer, 0, buffer.Length);
            return Encoding.UTF8.GetString(buffer);
        }
        public static string ReadUTFBytes(this Stream strm, int length)
        {
            var buffer = new byte[length];
            strm.Read(buffer, 0, buffer.Length);
            return Encoding.UTF8.GetString(buffer);
        }
        public static void WriteUTF(this Stream strm, string s)
        {
            var buffer = Encoding.UTF8.GetBytes(s);
            strm.WriteShort((short)buffer.Length);
            strm.Write(buffer, 0, buffer.Length);
        }
        public static void WriteUTFBytes(this Stream strm, string s)
        {

            var buffer = Encoding.UTF8.GetBytes(s);
            strm.Write(buffer, 0, buffer.Length);
        }
        /// <summary>
        /// 将流指针重置为0
        /// </summary>
        /// <param name="strm"></param>
        public static void ResetStreamPointer(this Stream strm)
        {
            strm.Position = 0;
        }
        public static string  GetPackageName(this Stream strm)
        {
            var name = strm.ReadUTF ();
            strm.Position = 0;
            return name;
        }
        /// <summary>
        /// 对传递给该流的消息进行打包
        /// </summary>
        /// <param name="strm">当前内存流</param>
        /// <param name="lastBuffer">上一次剩余的数据</param>
        /// <param name="receivedBuffer">本次接收到的数据</param>
        /// <param name="receivedLength">本次接收数据的长度</param>
        /// <returns>数据包的集合</returns>
        public static Message WrapMessage(this Stream strm, byte[] lastBuffer)
        {
            Message m = new Message();
            MemoryStream msg = strm as MemoryStream;
            var currentLength = msg.Length;
            //@指令｜内容长度｜内容#
            while (true)
            {
                //var start = msg.ReadByte();
                //if (start != 40)//此包不是以@开头，则认为是一个坏包
                //{

                //}
                int command = msg.ReadShort();
                if (command == -1)
                {
                    break;
                }
                int contentLength = msg.ReadShort();
                if (contentLength == -1)
                {
                    MemoryStream ms = new MemoryStream();
                    ms.WriteShort((short)command);
                    lastBuffer = ms.ToArray();
                    break;
                }
                MemoryStream currentMessage = new MemoryStream();
                currentMessage.WriteShort((short)command);
                currentMessage.WriteShort((short)contentLength);
                var currentBuffer = new byte[contentLength];
                int realLength = msg.Read(currentBuffer, 0, contentLength);
                currentMessage.Write(currentBuffer, 0, realLength);
                if (realLength == contentLength)
                {
                    m.Packages.Add(currentMessage);
                }
                else
                {
                    lastBuffer = currentMessage.ToArray();
                    currentMessage.Close();
                    break;
                }

            }
            msg.Close();
            GC.Collect();
            return m
;
        }
    }
}
